﻿using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using Common;
using Common.Enum;
using Common.NotifyEvent;
using Microsoft.Win32;
using SProject;
using SProject.Paramter;
using SProject.Rule;

namespace ProjectView.RuleView
{
    public partial class UCRule : UserControl
    {
        public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(UCRule), new UIPropertyMetadata(false));

        public static readonly DependencyProperty ProjectProperty = DependencyProperty.Register("Project", typeof(Project), typeof(UCRule), new UIPropertyMetadata(null, OnProjectChanged));

        private string dataFormat = DataFormats.Rtf;

        public bool IsReadOnly
        {
            get
            {
                return (bool)GetValue(IsReadOnlyProperty);
            }
            set
            {
                SetValue(IsReadOnlyProperty, value);
            }
        }

        public Project Project
        {
            get
            {
                return (Project)GetValue(ProjectProperty);
            }
            set
            {
                SetValue(ProjectProperty, value);
            }
        }

        private static void OnProjectChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            UCRule uCRule = sender as UCRule;
            if (uCRule != null && uCRule.Project != null)
            {
                uCRule.RefreshTabControl();
                uCRule.RegisteEvent();
                uCRule.LoadRuleNote();
            }
        }

        public UCRule()
        {
            InitializeComponent();
        }

        private void LoadRuleNote()
        {
            trbAdvRuleNote.Document.Blocks.Clear();
            if (Project != null && Project.Rule.AdvRuleNote != null)
            {
                TextRange textRange = new TextRange(trbAdvRuleNote.Document.ContentStart, trbAdvRuleNote.Document.ContentEnd);
                StreamEx streamEx = new StreamEx();
                streamEx.Write(Project.Rule.AdvRuleNote);
                streamEx.Seek(0L, SeekOrigin.Begin);
                textRange.Load(streamEx, dataFormat);
                streamEx.Close();
            }
        }

        private void SaveRuleNote()
        {
            if (Project != null)
            {
                TextRange textRange = new TextRange(trbAdvRuleNote.Document.ContentStart, trbAdvRuleNote.Document.ContentEnd);
                if (!textRange.IsEmpty)
                {
                    StreamEx streamEx = new StreamEx();
                    textRange.Save(streamEx, dataFormat);
                    streamEx.Seek(0L, SeekOrigin.Begin);
                    Project.Rule.AdvRuleNote = streamEx.ToArray();
                    streamEx.Close();
                }
            }
        }

        private void RegisteEvent()
        {
            if (Project != null)
            {
                Project.BasicInfo.Event += BasicInfo_Event;
            }
        }

        private void BasicInfo_Event(object sender, EventArgs e)
        {
            PropertyChangedEventArgsEx propertyChangedEventArgsEx = e as PropertyChangedEventArgsEx;
            if (propertyChangedEventArgsEx != null && propertyChangedEventArgsEx.PropertyName == "Type")
            {
                RefreshTabControl();
            }
        }

        private void RefreshTabControl()
        {
            tabItemBasicRule.Visibility = ((Project.BasicInfo.Type != 0 && Project.BasicInfo.Type != EProjectType.FastCal && Project.BasicInfo.Type != EProjectType.TQ && Project.BasicInfo.Type != EProjectType.IA) ? Visibility.Collapsed : Visibility.Visible);
            tabControlRule.RefreshTabItemStyle();
        }

        public bool Validate()
        {
            if (Project.Rule.BasicRule)
            {
                if (Project.Rule is AQRule && (!uCRuleTableExperimentIC.Validate() || !uCRuleTableSampleIC.Validate() || !uCRuleTableResuleRule.Validate()))
                {
                    tabItemBasicRule.IsSelected = true;
                    return false;
                }
            }
            else
            {
                if (Project.Rule.Data == null)
                {
                    tabItemAdvRule.IsSelected = true;
                    MessageBox.Show(Utility.GetMessage("msg_rulejudge_dll_invalid"));
                    textDllPath.Focus();
                    textDllPath.SelectAll();
                    return false;
                }
                string errorMsg;
                if (!ExecuteCommand.IsRuleJudgeDll(Project.Rule.Data, Utility.GetInternalVersion(), (int)Project.BasicInfo.Type, Project.BasicOption.Items.Select((BasicOptionItem s) => s.TargetName).ToArray(), Project.BasicOption.Items.Select((BasicOptionItem s) => s.ChannelNo).ToArray(), Project.BasicOption.Items.Select((BasicOptionItem s) => s.TubeNo).ToArray(), out errorMsg))
                {
                    if (string.IsNullOrEmpty(errorMsg))
                    {
                        errorMsg = Utility.GetMessage("msg_rulejudge_dll_invalid");
                    }
                    MessageBox.Show(errorMsg);
                    return false;
                }
            }
            SaveRuleNote();
            return true;
        }

        private void btnBrowse_Click(object sender, RoutedEventArgs e)
        {
            while (true)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Filter = string.Format("{0}{1}|*.{0}", "dll", Utility.GetMessage("File"));
                openFileDialog.FileName = string.Empty;
                openFileDialog.FilterIndex = 1;
                openFileDialog.RestoreDirectory = true;
                openFileDialog.DefaultExt = "dll";
                if (openFileDialog.ShowDialog() == true)
                {
                    byte[] array;
                    using (FileStream fileStream = File.OpenRead(openFileDialog.FileName))
                    {
                        array = new byte[fileStream.Length];
                        fileStream.Read(array, 0, array.Length);
                        fileStream.Close();
                    }
                    string errorMsg;
                    if (ExecuteCommand.IsRuleJudgeDll(array, Utility.GetInternalVersion(), (int)Project.BasicInfo.Type, Project.BasicOption.Items.Select((BasicOptionItem s) => s.TargetName).ToArray(), Project.BasicOption.Items.Select((BasicOptionItem s) => s.ChannelNo).ToArray(), Project.BasicOption.Items.Select((BasicOptionItem s) => s.TubeNo).ToArray(), out errorMsg))
                    {
                        Project.Rule.DllPath = openFileDialog.FileName;
                        Project.Rule.Data = array;
                        Project.Rule.Version = ExecuteCommand.GetVersion(array);
                        break;
                    }
                    if (string.IsNullOrEmpty(errorMsg))
                    {
                        errorMsg = Utility.GetMessage("msg_rulejudge_dll_invalid");
                    }
                    MessageBox.Show(errorMsg);
                    continue;
                }
                break;
            }
        }

        private void btnAddExperimentICRule_Click(object sender, RoutedEventArgs e)
        {
            if (Project != null && Project.Rule is AQRule)
            {
                ((AQRule)Project.Rule).ExperimentICRule.Items.Add(new RuleItem
                {
                    SampleType = SampleType.HighPositive
                });
            }
        }

        private void btnDeleteExperimentICRule_Click(object sender, RoutedEventArgs e)
        {
            if (Project == null || !(Project.Rule is AQRule))
            {
                return;
            }
            foreach (object item in uCRuleTableExperimentIC.GetSelectedItem())
            {
                ((AQRule)Project.Rule).ExperimentICRule.Items.Remove(item as RuleItem);
            }
        }

        private void btnAddSampleICRule_Click(object sender, RoutedEventArgs e)
        {
            if (Project != null && Project.Rule is AQRule)
            {
                ((AQRule)Project.Rule).SampleICRule.Items.Add(new RuleItem
                {
                    SampleType = SampleType.Unknown
                });
            }
        }

        private void btnDeleteSampleICRule_Click(object sender, RoutedEventArgs e)
        {
            if (Project == null || !(Project.Rule is AQRule))
            {
                return;
            }
            foreach (object item in uCRuleTableSampleIC.GetSelectedItem())
            {
                ((AQRule)Project.Rule).SampleICRule.Items.Remove(item as RuleItem);
            }
        }

        private void btnAddResultRule_Click(object sender, RoutedEventArgs e)
        {
            if (Project != null && Project.Rule is AQRule)
            {
                ((AQRule)Project.Rule).ResuleRule.Items.Add(new RuleItem
                {
                    SampleType = SampleType.Unknown
                });
            }
        }

        private void btnDeleteResultRule_Click(object sender, RoutedEventArgs e)
        {
            if (Project == null || !(Project.Rule is AQRule))
            {
                return;
            }
            foreach (object item in uCRuleTableResuleRule.GetSelectedItem())
            {
                ((AQRule)Project.Rule).ResuleRule.Items.Remove(item as RuleItem);
            }
        }

        [GeneratedCode("PresentationBuildTasks", "4.0.0.0")]
        [DebuggerNonUserCode]
        internal Delegate _CreateDelegate(Type delegateType, string handler)
        {
            return Delegate.CreateDelegate(delegateType, this, handler);
        }
    }
}
